package com.alibaba.sdk.service.impl;

import com.alibaba.sdk.annotation.BaseService;
import com.alibaba.sdk.constant.ApplicationErrorConstant;
import com.alibaba.sdk.enums.UserTypeEnum;
import com.alibaba.sdk.model.OperationResult;
import com.alibaba.sdk.model.dao.UserMapper;
import com.alibaba.sdk.model.dto.UserDTO;
import com.alibaba.sdk.model.entity.User;
import com.alibaba.sdk.model.input.LoginInput;
import com.alibaba.sdk.model.input.UserTypeInput;
import com.alibaba.sdk.model.output.LoginResponse;
import com.alibaba.sdk.service.LoginAndOutService;
import com.alibaba.sdk.service.UserService;
import com.alibaba.sdk.util.EncryptUtil;
import com.alibaba.sdk.util.SessionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;


/**
 * 用户登入登出服务实现类
 *
 * @author huangTT(bluehtt @ gmail.com)
 * @author Shawn(Shawn_0108 @ 163.com)
 * @version 1.0
 * @date 2020/6/4
 */
@Slf4j
@BaseService
public class LoginAndOutServiceImpl implements LoginAndOutService {

    @Resource
    private UserMapper userMapper;

    @Autowired
    private UserService userService;

    /**
     * 用户登入
     *
     * @param loginInput 用户登入参数类
     * @return
     */
    @Override
    public OperationResult<LoginResponse> login(LoginInput loginInput) {
        // 根据用户名获取用户信息
        User user = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getUsername, loginInput.getUsername()));
        if (Objects.isNull(user)) {
            log.warn("用户名不存在: username=[{}]", loginInput.getUsername());
            return OperationResult.failWithCode(ApplicationErrorConstant.WRONG_USERNAME_OR_PASSWORD);
        }
        if (!Objects.equals(EncryptUtil.getEncryptPassword(loginInput.getPassword()), user.getPassword())) {
            log.warn("密码错误: username=[{}]", loginInput.getUsername());
            return OperationResult.failWithCode(ApplicationErrorConstant.WRONG_USERNAME_OR_PASSWORD);
        }

        // 用户登录
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken passwordToken = new UsernamePasswordToken(loginInput.getUsername(), user.getPassword(), true);
        subject.login(passwordToken);

        // 设置返回
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        Optional<UserTypeEnum> first = Arrays.stream(UserTypeEnum.values()).filter(userType -> Objects.equals(userType, user.getUserType())).findFirst();
        UserTypeEnum userType = first.orElse(UserTypeEnum.USER);
        userDTO.setUserType(userType.getName());
        return OperationResult.success(userDTO);
    }

    /**
     * 用户登出
     *
     * @return
     */
    @Override
    public OperationResult logout() {
        SessionUtil.logout();
        return OperationResult.success();
    }
}
